package translinkApp.views.map;

import java.util.ArrayList;

import translinkApp.Activities.MapViewActivity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.location.Address;
import android.view.GestureDetector;
import android.view.GestureDetector.OnDoubleTapListener;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapView;
import com.google.android.maps.OverlayItem;

public class TransMapOverlay extends ItemizedOverlay implements OnGestureListener {

	private GestureDetector gestureDetector;
	private OnGestureListener onGestureListener;
	private final MapViewActivity mapActivity;
	private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
	private final OverlaySelectedListener listner;
	
	public interface OverlaySelectedListener {
		void onOverlaySelected(OverlayItem item);
	}

	public TransMapOverlay(Drawable defaultMarker, final MapViewActivity mapActivity, OverlaySelectedListener listner) {
		super(boundCenterBottom(defaultMarker));
		this.mapActivity = mapActivity;
		this.listner = listner;
		
		setLastFocusedIndex(-1);
		populate();
		
		gestureDetector = new GestureDetector(this);
		gestureDetector.setOnDoubleTapListener(new OnDoubleTapListener() {

			@Override
			public boolean onSingleTapConfirmed(MotionEvent e) {
				return false;
			}

			@Override
			public boolean onDoubleTapEvent(MotionEvent e) {
				return false;
			}

			@Override
			public boolean onDoubleTap(MotionEvent e) {

				mapActivity.getMapController().zoomIn();
				mapActivity.getMapController().animateTo(
						mapActivity.getMapView().getProjection()
								.fromPixels((int) e.getX(), (int) e.getY()));
				return false;
			}
		});
	}

	public void addOverlay(OverlayItem overlay) {
		mOverlays.add(overlay);

		setLastFocusedIndex(-1);
		populate();
	}

	@Override
	protected OverlayItem createItem(int i) {
		OverlayItem item = mOverlays.get(i);
		Drawable drawable = item.getMarker(0);

		if (drawable != null) {
			int w = drawable.getIntrinsicWidth();
			int h = drawable.getIntrinsicHeight();

			drawable.setBounds(0, 0, w, h);

			item.setMarker(boundCenterBottom(drawable));
		}

		return item;
	}

	@Override
	public int size() {
		return mOverlays.size();
	}

	@Override
	public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when) {
		super.draw(canvas, mapView, shadow, when);

		// ---translate the GeoPoint to screen pixels---
		if (mapActivity.getPinnedLocation() != null) {
			Bitmap bmp = BitmapFactory.decodeResource(mapActivity.getResources(),
					android.R.drawable.ic_menu_edit);
			drawPoint(mapView, canvas, mapActivity.getPinnedLocation(), bmp);
		}

		return true;
	}

	private void drawPoint(MapView mapView, Canvas canvas, GeoPoint point, Bitmap bmp) {
		Point screenPts = new Point();
		mapView.getProjection().toPixels(point, screenPts);

		canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 50, null);
	}

	public boolean onTouchEvent(MotionEvent event, MapView mapView) {
		if (gestureDetector.onTouchEvent(event)) {
			return true;
		}
		return false;

	}

	@Override
	public boolean onDown(MotionEvent e) {
		if (onGestureListener != null) {
			return onGestureListener.onDown(e);
		}
		return false;
	}

	@Override
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
		if (onGestureListener != null) {
			return onGestureListener.onFling(e1, e2, velocityX, velocityY);
		}
		return false;
	}

	@Override
	public void onLongPress(MotionEvent e) {

		GeoPoint tempPoint = mapActivity.getMapView().getProjection()
				.fromPixels((int) e.getX(), (int) e.getY());

		Address addressObj = mapActivity.getAddress(tempPoint);

		if (addressObj != null) {

			mapActivity.setPinnedLocation(tempPoint);

			String address = addressObj.getAddressLine(0);
			String data = address;
			String suburb = "";
			try {
				suburb = addressObj.getAddressLine(1);

				String[] suburbs = suburb.split(" ");

				suburb = "";
				for (int i = 0; i < suburbs.length - 2; i++) {
					suburb = suburb + suburbs[i] + " ";
				}
				suburb = suburb.trim();
				data = data + ", " + suburb;
			} catch (Exception ex) {
				suburb = "";
			}

			mapActivity.setAddressText(data);
			mapActivity.setCurrentAddress(data);

			Toast.makeText(mapActivity.getBaseContext(), data, Toast.LENGTH_SHORT).show();
		}

		if (onGestureListener != null) {
			onGestureListener.onLongPress(e);
		}
	}

	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
		if (onGestureListener != null) {
			onGestureListener.onScroll(e1, e2, distanceX, distanceY);
		}
		return false;
	}

	@Override
	public void onShowPress(MotionEvent e) {
		if (onGestureListener != null) {
			onGestureListener.onShowPress(e);
		}
	}

	@Override
	public boolean onSingleTapUp(MotionEvent e) {
		if (onGestureListener != null) {
			onGestureListener.onSingleTapUp(e);

		}
		return false;
	}

	public boolean isLongpressEnabled() {
		return gestureDetector.isLongpressEnabled();
	}

	public void setIsLongpressEnabled(boolean isLongpressEnabled) {
		gestureDetector.setIsLongpressEnabled(isLongpressEnabled);
	}

	public OnGestureListener getOnGestureListener() {
		return onGestureListener;
	}

	public void setOnGestureListener(OnGestureListener onGestureListener) {
		this.onGestureListener = onGestureListener;
	}

	@Override
	protected boolean onTap(int index) {
		if (index < 0) {
			return false;
		}
		final OverlayItem item = mOverlays.get(index);
		AlertDialog.Builder dialog = new AlertDialog.Builder(mapActivity);
		dialog.setTitle(item.getTitle());
		dialog.setMessage(item.getSnippet());
		dialog.setPositiveButton("Select station", new OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				listner.onOverlaySelected(item);
			}
		});

		dialog.setNegativeButton("Cancel", null);

		dialog.show();
		return true;
	}

	public void clearOverlay() {
		mOverlays.clear();

		setLastFocusedIndex(-1);
		populate();
	}

}
